rust
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::borrow::Borrow;

type ListValue = i32; // Assuming the list holds integer values for simplicity.

// Define a node in the doubly-linked list
#[derive(Clone)]
struct ListEntry {
    data: RefCell<ListValue>,
    prev: RefCell<Option<Weak<ListEntry>>>,
    next: RefCell<Option<Rc<ListEntry>>>,
}

// Define the doubly-linked list
struct DoublyLinkedList {
    head: RefCell<Option<Rc<ListEntry>>>,
    tail: RefCell<Option<Weak<ListEntry>>>,
    length: RefCell<usize>,
}

impl DoublyLinkedList {
    // Function to remove a specific entry from the list
    fn remove_entry(&self, entry: Rc<ListEntry>) -> bool {
        if let Some(ref prev_entry) = *entry.prev.borrow() {
            let prev_entry_upgraded: Rc<ListEntry> = prev_entry.upgrade().unwrap();
            *prev_entry_upgraded.borrow_mut().next.borrow_mut() = entry.borrow().next.borrow().clone();
        } else {
            *self.head.borrow_mut() = entry.borrow().next.borrow().clone();
        }

        if let Some(ref next_entry) = *entry.borrow().next.borrow() {
            *next_entry.borrow_mut().prev.borrow_mut() = Some(Rc::downgrade(&entry));
        } else {
            *self.tail.borrow_mut() = Some(Rc::downgrade(&entry));
        }

        *self.length.borrow_mut() -= 1;
        true
    }

    // Dummy implementation of `new`, `append`, and `nth_entry` to make the code compile
    fn new() -> Self {
        DoublyLinkedList {
            head: RefCell::new(None),
            tail: RefCell::new(None),
            length: RefCell::new(0),
        }
    }

    fn append(&self, value: ListValue) {
        let new_entry = Rc::new(ListEntry {
            data: RefCell::new(value),
            prev: RefCell::new(None),
            next: RefCell::new(None),
        });

        if let Some(ref mut tail) = *self.tail.borrow_mut() {
            let tail_entry: Rc<ListEntry> = tail.upgrade().unwrap();
            *tail_entry.borrow_mut().next.borrow_mut() = Some(new_entry.clone());
            new_entry.prev.replace(Some(Rc::downgrade(&tail_entry)));
        } else {
            *self.head.borrow_mut() = Some(new_entry.clone());
        }

        *self.tail.borrow_mut() = Some(Rc::downgrade(&new_entry));
        *self.length.borrow_mut() += 1;
    }

    fn nth_entry(&self, index: usize) -> Option<Rc<ListEntry>> {
        let mut current = self.head.borrow().clone();
        for _ in 0..index {
            if let Some(ref entry) = *current {
                current = entry.borrow().next.borrow().clone();
            } else {
                return None;
            }
        }
        current
    }

    fn data(entry: &Rc<ListEntry>) -> RefMut<ListValue> {
        entry.data.borrow_mut()
    }
}

fn main() {
    let list = DoublyLinkedList::new();

    list.append(1);
    list.append(2);
    list.append(3);

    if let Some(entry) = list.nth_entry(1) {
        println!("Data at position 1: {}", *DoublyLinkedList::data(&entry));
    }

    // ... and so on for other methods.
}

